<html>
<head>
	<base href="${basePath}">
	<title>应用监控</title>
	<style>
		html, body {
			margin: 0;
			height: 100%;
			overflow: hidden;
			color: var(--dark);
		}
		:root{
			--primary: #409EFF;
			--warn: #E6A23C;
			--danger: #F56C6C;
			--info: #909399;
			--success: #67C23A;
			--darker : #000;
			--dark: #303133;
			--gray: #606266;
			--light : #cdd1d9;

			--lighter : #f1f1f1;
			--border : #DCDFE6;
		}
		*{
			flex-shrink:0;
			letter-spacing: .5px;
		}
		html, body{
			height: 100%;
			overflow: hidden;
			font-size: 16px;
		}
		.hide{
			display:none !important;
		}

		.fx{
			display:flex;
			flex-direction:row;
		}

		.fx-col{
			display:flex;
			flex-direction:column;
			align-items: stretch;
		}

		.fx-g1{
			flex-grow:1;
			flex-shrink:1;
			overflow:auto;
		}
		.fx-g2{
			flex:2;
		}
		.fx-g3{
			flex:3;
		}
		.fx-g4{
			flex:4;
		}
		.fx-g5{
			flex:5;
		}
		.noshrink{
			flex-shrink:0;
		}
		/**主轴排列**/
		.fx-m_start{
			justify-content : flex-start;
		}
		.fx-m_end{
			justify-content : flex-end;
		}
		.fx-m_center{
			justify-content : center;
		}
		.fx-m_between{
			justify-content : space-between;
		}
		.fx-m_around{
			justify-content : space-around;
		}
		/**交叉轴排列**/
		.fx-c_start{
			align-items : flex-start;
		}
		.fx-c_end{
			align-items : flex-end;
		}
		.fx-c_center{
			align-items : center;
		}
		.fx-c_baseline{
			align-items : baseline;
		}
		.fx-c_stretch{
			align-items : stretch;
		}
		.fx-center{
			justify-content : center;
			align-items : center;
		}
		.fx-wrap{
			flex-wrap: wrap;
		}
		.fl{
			float:left;
		}
		.fr{
			float:right;
		}
		.text_primary {
			color: var(--primary) !important;
		}
		.text_success {
			color: var(--success) !important;
		}
		.text_danger {
			color: var(--danger) !important;
		}
		.text_warn {
			color: var(--warn) !important;
		}
		.text_info {
			color: var(--info) !important;
		}
		.text_dark {
			color: var(--dark) !important;
		}
		.text_normal {
			color: var(--gray) !important;
		}
		.text_light {
			color: var(--light) !important;
		}
		.text_ligher {
			color: var(--lighter) !important;
		}
		.font12 {
			font-size: 12px !important;
		}
		.font14{
			font-size: 14px !important;
		}
		.font16 {
			font-size: 16px !important;
		}
		.font18 {
			font-size: 18px !important;
		}
		.font20 {
			font-size: 20px !important;
		}
		.font22 {
			font-size: 22px !important;
		}
		.font24 {
			font-size: 24px !important;
		}
		.font26 {
			font-size: 26px !important;
		}
		.font28 {
			font-size: 28px !important;
		}
		.font30 {
			font-size: 30px !important;
		}
		.padding5 {
			padding: 5px;
		}
		.padding10 {
			padding: 10px;
		}
		.padding15 {
			padding: 15px;
		}
		.tl {
			text-align: left;
		}
		.tc {
			text-align: center;
		}
		.tr {
			text-align: right;
		}
		.ellipsis{
			overflow: hidden;
			text-overflow: ellipsis;
			white-space: nowrap;
		}

		.ml10 {
			margin-left: 10px;
		}
		.mr10 {
			margin-right: 10px;
		}
		.mt10 {
			margin-top: 10px;
		}
		.mb10 {
			margin-bottom: 10px;
		}
		.ml15 {
			margin-left: 15px;
		}
		.mr15 {
			margin-right: 15px;
		}
		.mt15 {
			margin-top: 15px;
		}
		.mb15 {
			margin-bottom: 15px;
		}
		.ml20 {
			margin-left: 20px;
		}
		.mr20 {
			margin-right: 20px;
		}
		.mt20 {
			margin-top: 20px;
		}
		.mb20 {
			margin-bottom: 20px;
		}
		.ml30 {
			margin-left: 30px;
		}
		.mr30 {
			margin-right: 30px;
		}
		.mt30 {
			margin-top: 30px;
		}
		.mb30 {
			margin-bottom: 30px;
		}
		.ml40 {
			margin-left: 40px;
		}
		.mr40 {
			margin-right: 40px;
		}
		.mt40 {
			margin-top: 40px;
		}
		.mb40 {
			margin-bottom: 40px;
		}
		.pointer{
			cursor: pointer;
			user-select: none;
		}
		*::-webkit-scrollbar {
			/*滚动条整体样式, 需要排除table 滚动条样式*/
			width : 10px;  /*高宽分别对应横竖滚动条的尺寸*/
			height: 10px;
		}
		*::-webkit-scrollbar-thumb {
			/*滚动条里面小方块*/
			border-radius: 10px;
			box-shadow   : inset 0 0 5px rgba(52, 64, 64, 0.2);
			background   : #667d9a;
		}
		*::-webkit-scrollbar-track {
			/*滚动条里面轨道*/
			box-shadow   : inset 0 0 5px rgba(0, 0, 0, 0.2);
			border-radius: 10px;
			background   : #344040;
		}
		.is-scrolling-left::-webkit-scrollbar,.is-scrolling-right::-webkit-scrollbar,.is-scrolling-middle::-webkit-scrollbar{
			width : 5px;  /*高宽分别对应横竖滚动条的尺寸*/
			height: 10px;
		}
		.is-scrolling-left::-webkit-scrollbar-thumb,.is-scrolling-right::-webkit-scrollbar-thumb,.is-scrolling-middle::-webkit-scrollbar-thumb {
			/*滚动条里面小方块*/
			border-radius: 10px;
			box-shadow   : inset 0 0 5px rgba(52, 64, 64, 0.2);
			background   : #344040;
		}
		.is-scrolling-left::-webkit-scrollbar-track,.is-scrolling-right::-webkit-scrollbar-track,.is-scrolling-middle::-webkit-scrollbar-track {
			/*滚动条里面轨道*/
			box-shadow   : inset 0 0 5px rgba(0, 0, 0, 0.2);
			border-radius: 10px;
			background   : white;
		}
		a {
			color: inherit;
			text-decoration: none;
		}
		.main {
			width: 100%;
			height: 100%;
		}
		.page_nav {
			padding: 15px 20px;
			border-bottom: 1px solid var(--border);
		}
		.page_nav a {
			padding: 0 15px;
			border-right: 1px solid var(--border);
			cursor: pointer;
		}
		.page_nav a:first-child{
			border-left: 1px solid var(--border);
		}
		.page_nav a.active{
			font-weight: bold;
		}
		.panel {
			width: 100%;
			height: 100%;
			overflow: auto;
		}
		.panel_half {
			width: 50%;
			box-sizing: border-box;
			padding: 15px;
		}
		.block label.title {
			padding: 5px 10px;
			background: var(--lighter);
			font-size: 14px;
			color: var(--gray);
		}
		.block .block_chart{
			width: calc(49vw - 30px);
			height: 250px;
		}
		.cycle_list {
			list-style: none;
			margin:0;
			margin-left: 30px;
		}
		.cycle_list .cycle {
			padding: 5px 10px;
			font-size: 12px;
			cursor: pointer;
			background: var(--lighter);
		}
		.cycle_list .cycle.active{
			background: var(--light);
		}
		.toggle_btn-inner{
			position:relative;
			width:50px;
			height:26px;
			background:linear-gradient(dimgray, silver);
			border-radius:13px;
			box-shadow:0 0 0 6px rgba(255,255,255,0.7);
		}
		.toggle_btn-inner::before{
			content:'关';
			font-size:12px;
			color:#808080;
			line-height:25px;
			text-align:center;
			position:absolute;
			left:0px;
			width:26px;
			height:26px;
			background:radial-gradient(whitesmoke ,silver );
			border-radius:13px;
			transition:left 0.5s ease-in-out;
		}
		.toggle_btn{
			position:absolute;
			width:50px;
			height:26px;
			z-index:3;
			cursor:pointer;
			filter:opacity(0%);
		}
		.toggle_btn:checked ~ .toggle_btn-inner::before{
			content:"开";
			color:limegreen;
			left:50%;
		}
		.toggle_btn:checked ~ .toggle_btn-inner{
			background:linear-gradient(green,limegreen);
		}
		.block span.label {
			color: var(--darker);
		}
		table {
			border: 1px solid var(--border);
			border-collapse: collapse;
			width: 100%;
		}
		th{
			background: var(--lighter);
		}

		td,th{
			border: 1px solid var(--border);
			padding: 10px;
			text-align: center;
			vertical-align: middle;
		}
		tr td.params {
			text-align: left;
			padding-left: 40px;
		}

	</style>
</head>
<body >
	<div class="main fx-col">
		<nav class="page_nav noshrink">
			<a data-panel="server" class="active">服务器运行状态</a>
			<a data-panel="app">应用运行状态</a>
			<a data-panel="controller">Controller面板</a>
			<a data-panel="interceptor" >Interceptor面板</a>
			<a data-panel="bootedhandler" >BootedHandler面板</a>

			<div style="float:right" class="fx fx-c_start">
				<span>是否开启监控：</span>
				<div style="display:inline-block; position: relative;">
					<input ${enable?string("checked","")} type="checkbox" class="toggle_btn" id="enable_btn">
					<div class="toggle_btn-inner">
					</div>
				</div>
			</div>
		</nav>

		<div class="fx-g1" >
			<!-- 系统监控相关 -->
			<div id="server" class="panel fx fx-c_stretch ">
				<div class="panel_half">
					<div class="block">
						<div class="fx fx-c_end">
							<label  class="title">服务器CPU使用情况</label>
							<ul class="fx cycle_list fx-c_baseline">
								<li class="cycle active" data-category="system_cpu" data-cycle="secondData">最近半小时</li>
								<li class="cycle" data-category="system_cpu" data-cycle="miniteData" >最近一小时</li>
								<li class="cycle" data-category="system_cpu" data-cycle="hourData">最近一天</li>
							</ul>
						</div>
						<div id="system_cpu" class="block_chart"></div>
					</div>
					<div class="block mt20">
						<div class="fx fx-c_end">
							<label  class="title">服务器内存使用情况</label>
							<ul class="fx cycle_list fx-c_baseline">
								<li class="cycle active" data-category="system_memory" data-cycle="secondData">最近半小时</li>
								<li class="cycle" data-category="system_memory" data-cycle="miniteData" >最近一小时</li>
								<li class="cycle" data-category="system_memory" data-cycle="hourData">最近一天</li>
							</ul>
						</div>
						<div id="system_memory" class="block_chart"></div>
					</div>
					<div class="block mt20">
						<div class="fx fx-c_end">
							<label  class="title">网络读取速率 MB/s</label>
							<ul class="fx cycle_list fx-c_baseline">
								<li class="cycle active" data-category="net_read" data-cycle="secondData">最近半小时</li>
								<li class="cycle" data-category="net_read" data-cycle="miniteData" >最近一小时</li>
								<li class="cycle" data-category="net_read" data-cycle="hourData">最近一天</li>
							</ul>
						</div>
						<div id="net_read" class="block_chart"></div>
					</div>
					<div class="block mt20">
						<div class="fx fx-c_end">
							<label  class="title">网络写入速率 MB/s</label>
							<ul class="fx cycle_list fx-c_baseline">
								<li class="cycle active" data-category="net_write" data-cycle="secondData">最近半小时</li>
								<li class="cycle" data-category="net_write" data-cycle="miniteData" >最近一小时</li>
								<li class="cycle" data-category="net_write" data-cycle="hourData">最近一天</li>
							</ul>
						</div>
						<div id="net_write" class="block_chart"></div>
					</div>
				</div>
				<div class="panel_half">
					<div class="block" style="border-bottom: 1px solid var(--border)">
						<div class="fx fx-c_end">
							<label class="title">服务器基本信息</label>
						</div>
						<div id="system_info" class="mt20 fx-col ">
							
						</div>
					</div>
					<div class="block mt20">
						<div class="fx fx-c_end">
							<label  class="title">存储使用情况</label>
						</div>
						<div id="system_store" class="block_chart"></div>
					</div>
					<div class="block mt20">
						<div class="fx fx-c_end">
							<label  class="title">磁盘读取速率 MB/s</label>
							<ul class="fx cycle_list fx-c_baseline">
								<li class="cycle active" data-category="disk_read" data-cycle="secondData">最近半小时</li>
								<li class="cycle" data-category="disk_read" data-cycle="miniteData" >最近一小时</li>
								<li class="cycle" data-category="disk_read" data-cycle="hourData">最近一天</li>
							</ul>
						</div>
						<div id="disk_read" class="block_chart"></div>
					</div>
					<div class="block mt20">
						<div class="fx fx-c_end">
							<label  class="title">磁盘写入速率 MB/s</label>
							<ul class="fx cycle_list fx-c_baseline">
								<li class="cycle active" data-category="disk_write" data-cycle="secondData">最近半小时</li>
								<li class="cycle" data-category="disk_write" data-cycle="miniteData" >最近一小时</li>
								<li class="cycle" data-category="disk_write" data-cycle="hourData">最近一天</li>
							</ul>
						</div>
						<div id="disk_write" class="block_chart"></div>
					</div>

				</div>
			</div>




			<!-- 应用监控相关 -->
			<div id="app" class="panel fx fx-c_stretch hide">
				<div class="panel_half">
					<div class="block">
						<div class="fx fx-c_end">
							<label >JVM CPU占用情况</label>
							<ul class="fx cycle_list fx-c_baseline">
								<li class="cycle active" data-category="app_cpu" data-cycle="secondData">最近半小时</li>
								<li class="cycle" data-category="app_cpu" data-cycle="miniteData" >最近一小时</li>
								<li class="cycle" data-category="app_cpu" data-cycle="hourData">最近一天</li>
							</ul>
						</div>
						<div id="app_cpu" class="block_chart"></div>
					</div>

					<div class="block mt20">
						<div class="fx fx-c_end">
							<label >JVM 线程数</label>
							<ul class="fx cycle_list fx-c_baseline">
								<li class="cycle active" data-category="app_thread" data-cycle="secondData">最近半小时</li>
								<li class="cycle" data-category="app_thread" data-cycle="miniteData" >最近一小时</li>
								<li class="cycle" data-category="app_thread" data-cycle="hourData">最近一天</li>
							</ul>
						</div>
						<div id="app_thread" class="block_chart"></div>
					</div>
				</div>
				<div class="panel_half">
					<div class="block mt20">
						<div class="fx fx-c_end">
							<label >JVM 内存占用情况</label>
							<ul class="fx cycle_list fx-c_baseline">
								<li class="cycle active" data-category="app_memory" data-cycle="secondData">最近半小时</li>
								<li class="cycle" data-category="app_memory" data-cycle="miniteData" >最近一小时</li>
								<li class="cycle" data-category="app_memory" data-cycle="hourData">最近一天</li>
							</ul>
						</div>
						<div id="app_memory" class="block_chart"></div>
					</div>
				</div>
			</div>


			<!-- Controller监控相关 -->
			<div id="controller" class="panel hide" style="padding:15px;box-sizing: border-box">
				<table>
					<thead>
					<tr>
						<th width="20%">Controller类</th>
						<th width="10%">方法</th>
						<th width="30%">参数</th>
						<th width="40%">url</th>
					</tr>
					</thead>
					<tbody id="controller_list">

					</tbody>
				</table>

			</div>

			<!-- interceptor监控相关 -->
			<div id="interceptor" class="panel hide" style="padding:15px;box-sizing: border-box">
				<table>
					<thead>
					<tr>
						<th>优先级</th>
						<th >ControllerInterceptor类</th>
						<th >备注</th>
					</tr>
					</thead>
					<tbody id="interceptor_list">

					</tbody>
				</table>

			</div>
			<!-- interceptor监控相关 -->
			<div id="bootedhandler" class="panel hide" style="padding:15px;box-sizing: border-box">
				<table>
					<thead>
					<tr>
						<th>序号</th>
						<th >BootedHandler类</th>
						<th >备注</th>
					</tr>
					</thead>
					<tbody id="bootedhandler_list">

					</tbody>
				</table>

			</div>
		</div>
	</div>

</body>


<script src="https://cdn.bootcdn.net/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script src="https://cdn.bootcdn.net/ajax/libs/echarts/5.0.0-rc.1/echarts.min.js"></script>
<script>
$(function () {
	$(document).on("click", ".page_nav a", function () {
		if($(this).hasClass("active")) return;
		let panel = $(this).data("panel");
		let prevPanel = $(".page_nav a.active").data("panel");
		$("#"+prevPanel).addClass("hide");
		$(".page_nav a.active").removeClass("active");
		$(this).addClass("active");
		$("#"+panel).removeClass("hide");
		initPanels();
	}).on("click", ".cycle", function () {
		if($(this).hasClass("active")) return;
		let category = $(this).data("category");
		let cycle = $(this).data("cycle");
		items[category].cycle = cycle;
		processChart(category);
		$(this).siblings(".active").removeClass("active");
		$(this).addClass("active");
	}).on("click", "#enable_btn", function () {
		monitorEnable = $(this).prop("checked");
		send({type:"enable_monitor", value: monitorEnable});
	}).on("keydown", "body", function (e) {
		var id = $(".page_nav a.active").data("panel");
		if (e.keyCode==9) { //tab键聚焦到搜索框
			switch (id) {
				case "controller":
					$("#controller_keywords").focus();
					e.stopPropagation();
					e.preventDefault();
					break;
			}
		}
	})


})

/**
 * 是否开启监控
 */
var monitorEnable = ${enable?string("true","false")};

var items = {
	"system_info": {
		name: "系统信息",
		group: "server",
		interval: 300
	},

	"system_cpu": {
		name:"CPU使用率",
		chart: null,
		cycle:"secondData",
		interval: 3,
		group:"server",
		allData:{},
		option: {
			title: {show: false}, legend:{show:false},grid:{left:40,top:30,right:30,bottom:30},
			tooltip:{trigger:"axis",axisPointer: {type:"cross",animation:false}},
			xAxis: { type: 'time', splitLine: { show: false } },
			yAxis: { type: 'value', axisLabel:{formatter: '{value} %'}},
			series: [{name: 'CPU使用率',type: 'line',hoverAnimation: false,showSymbol: false,animation:false,
				data: []}]
		}
	},
	"system_memory": {
		name:"内存使用",
		chart: null,
		cycle:"secondData",
		interval: 3,
		group:"server",
		allData:{},
		option: {
			title: {show: false}, legend:{show:false},grid:{left:60,top:30,right:50,bottom:30},
			tooltip:{trigger:"axis",axisPointer: {type:"cross",animation:false}},
			xAxis: { type: 'time', splitLine: { show: false } },
			yAxis: { type: 'value', axisLabel:{formatter: '{value} G'}},
			series: [{name: '内存使用',type: 'line',hoverAnimation: false,showSymbol: false,animation:false,
				data: []}]
		}
	},

	"system_store": {
		name:"系统存储",
		chart:null,
		interval: 0, //它的数据来源system_info，不单独请求
		group:"server",
		option: {
			color:["#B03A5B", "#91CC75"],
			tooltip: {trigger: 'axis',axisPointer: {	type: 'shadow'	},formatter: '{a0}: {c0}GB<br />{a1}: {c1}GB'}, legend:{show:false},
			grid: {top:30,	left: 40,right: 30},
			xAxis: {type: 'value'},
			yAxis: {type: 'category',data: []},
			series: [
				{name: '已用空间',type: 'bar',stack: '总量',label: {show: true,position: 'insideRight'},
					data: []},
				{name: '可用空间',type: 'bar',stack: '总量',label: {show: true,position: 'insideRight'},
					data: []}
			]
		}
	},
	"disk_read": {
		name:"磁盘读取",
		chart: null,
		cycle:"secondData",
		interval: 3,
		allData:{},
		group:"server",
		option: {
			title: {show: false}, legend:{show:false},grid:{left:60,top:30,right:50,bottom:30},
			tooltip:{trigger:"axis",axisPointer: {type:"cross",animation:false}},
			xAxis: { type: 'time', splitLine: { show: false } },
			yAxis: { type: 'value', axisLabel:{formatter: '{value} M'}},
			series: [{name: '磁盘读取',type: 'line',hoverAnimation: false,showSymbol: false,animation:false,
				data: []}]
		}
	},
	"disk_write": {
		name:"磁盘写入",
		chart: null,
		cycle:"secondData",
		interval: 3,
		allData:{},
		group:"server",
		option: {
			title: {show: false}, legend:{show:false},grid:{left:60,top:30,right:50,bottom:30},
			tooltip:{trigger:"axis",axisPointer: {type:"cross",animation:false}},
			xAxis: { type: 'time', splitLine: { show: false } },
			yAxis: { type: 'value', axisLabel:{formatter: '{value} M'}},
			series: [{name: '磁盘读取',type: 'line',hoverAnimation: false,showSymbol: false,animation:false,
				data: []}]
		}
	},
	"net_read": {
		name:"网络读取",
		chart: null,
		cycle:"secondData",
		interval: 3,
		group:"server",
		allData:{},
		option: {
			title: {show: false}, legend:{show:false},grid:{left:60,top:30,right:50,bottom:30},
			tooltip:{trigger:"axis",axisPointer: {type:"cross",animation:false}},
			xAxis: { type: 'time', splitLine: { show: false } },
			yAxis: { type: 'value', axisLabel:{formatter: '{value} M'}},
			series: [{name: '网络读取',type: 'line',hoverAnimation: false,showSymbol: false,animation:false,
				data: []}]
		}
	},
	"net_write": {
		name:"网络写入",
		chart: null,
		cycle:"secondData",
		interval: 3,
		allData:{},
		group:"server",
		option: {
			title: {show: false}, legend:{show:false},grid:{left:60,top:30,right:50,bottom:30},
			tooltip:{trigger:"axis",axisPointer: {type:"cross",animation:false}},
			xAxis: { type: 'time', splitLine: { show: false } },
			yAxis: { type: 'value', axisLabel:{formatter: '{value} M'}},
			series: [{name: '网络写入',type: 'line',hoverAnimation: false,showSymbol: false,animation:false,
				data: []}]
		}
	},
	"app_cpu": {
		name:"JVM CPU占用",
		chart: null,
		cycle:"secondData",
		interval: 3,
		allData:{},
		group:"app",
		option: {
			title: {show: false}, legend:{show:false},grid:{left:40,top:30,right:30,bottom:30},
			tooltip:{trigger:"axis",axisPointer: {type:"cross",animation:false}},
			xAxis: { type: 'time', splitLine: { show: false } },
			yAxis: { type: 'value', axisLabel:{formatter: '{value} %'}},
			series: [{name: 'CPU占用率',type: 'line',hoverAnimation: false,showSymbol: false,animation:false,
				data: []}]
		}
	},
	"app_memory": {
		name:"JVM内存占用",
		chart: null,
		cycle:"secondData",
		interval: 3,
		allData:{},
		group:"app",
		option: {
			title: {show: false}, legend:{show:false},grid:{left:60,top:30,right:50,bottom:30},
			tooltip:{trigger:"axis",axisPointer: {type:"cross",animation:false}},
			xAxis: { type: 'time', splitLine: { show: false } },
			yAxis: { type: 'value', axisLabel:{formatter: '{value} G'}},
			series: [{name: '内存占用',type: 'line',hoverAnimation: false,showSymbol: false,animation:false,
				data: []}]
		}
	},
	"app_thread": {
		name:"JVM 线程数",
		chart: null,
		cycle:"secondData",
		interval: 3,
		group:"app",
		allData:{},
		option: {
			title: {show: false}, legend:{show:false},grid:{left:60,top:30,right:50,bottom:30},
			tooltip:{trigger:"axis",axisPointer: {type:"cross",animation:false}},
			xAxis: { type: 'time', splitLine: { show: false } },
			yAxis: { type: 'value', axisLabel:{formatter: '{value} 个'}},
			series: [{name: 'JVM 线程数',type: 'line',hoverAnimation: false,showSymbol: false,animation:false,
				data: []}]
		}
	},
	"controller_info":{
		name: "Controller映射",
		interval: 10,
		group: "controller"
	},
	"interceptor_info":{
		name: "Interceptor拦截器",
		interval: 10,
		group: "interceptor"
	},
	"bootedhandler_info":{
		name: "BootedHandler启动回调",
		interval: 10,
		group: "bootedhandler"
	},
}


/**
 * 计时器，高频和低频的
 */
var timer = null;
var currentItems=[];
var startTime = null;
/**
 * 初始化各面板，这个函数是在socket链接创建成功后调用的
 */
function initPanels() {
	var id = $(".page_nav a.active").data("panel");
	if (timer) {
		clearInterval(timer);
	}
	let currentEntries = Object.entries(items).filter(entry => entry[1].group == id);

	startTime = Math.floor(new Date().getTime()/1000);
	timer = setInterval(() => {
		if (!monitorEnable) return;
		let now = Math.floor(new Date().getTime()/1000);

		currentEntries.forEach(entry => {

			let key = entry[0];
			let item = entry[1];
			if (!item.interval) return;

			if (item.option && item.chart == null) {
				item.chart = echarts.init(document.getElementById(key));
			}
			if (item.option) { //图表类
				if (now - startTime < 2) { //第一次上来就执行
					item.chart.setOption(item.option);
					send({type:"init_data", category:key});
				} else  if ((now - startTime)%item.interval == 0) {
					send({type: "update_data", category:key});
				}

			} else { //其他类
				if (now - startTime < 2) { //第一次上来就执行
					send({type: "update_data", category:key});
				} else if ((now - startTime)%item.interval == 0) {
					send({type: "update_data", category:key});
				}

			}
		})


	}, 1000)


}



/**
 * 解析后端传过来的信息
 */
function resolveMsg(msg) {
	let res = JSON.parse(msg);
	let {type, category, data} = res;
	if(type == "init_data") {
		processInitData(category, data);
	} else if (type == "update_data") {

		processUpdateData(category, data);
	}
}

/**
 * 处理初始化的数据
 */
function processInitData(category, data) {

	if (items[category] != null) {
		items[category].allData = data;
		processChart(category);
	}

}

/**
 * 处理图表数据
 */
function processChart(category) {
	let total = items[category].allData.total;
	if(total) {
		items[category].option.yAxis.max = total;
		items[category].chart.setOption({
			yAxis: {max: total}
		})
	}
	let data = items[category].allData[items[category].cycle];
	if(items[category].cycle == "secondData") {
		data = data.map(item => {
				return {value:[new Date(item.time).format("yyyy-MM-dd HH:mm:ss"), item.data]};
		} );
		items[category].chart.setOption({
			series: [{
				markPoint:{data:[{type:"max",name:"最大值"},{type:"min",name:"最小值"}]},
				markLine:{data:[{type:"average",name:"平均值"}]},
				data: data
			}]
		})
	} else {
		let name = items[category].name;
		let series = [
				{name:(name+"最大值"), type:"line",hoverAnimation: false,showSymbol: false,animation:false,data:[]},
				{name:(name+"最小值"), type:"line",hoverAnimation: false,showSymbol: false,animation:false,data:[]},
				{name:(name+"平均值"), type:"line",hoverAnimation: false,showSymbol: false,animation:false,data:[]}
		]
		data.forEach(item => {
			series[0].data.push({value:[new Date(item.time).format("yyyy-MM-dd HH:mm:ss"), item.max]});
			series[1].data.push({value:[new Date(item.time).format("yyyy-MM-dd HH:mm:ss"), item.min]});
			series[2].data.push({value:[new Date(item.time).format("yyyy-MM-dd HH:mm:ss"), item.avg]});
		})
		items[category].chart.setOption({
			series: series
		})
	}
}

/**
 * 处理更新数据
 * data中的每一个周期数据格式是
 * {size:后台该周期数据的最新数量，用于前端判断该插入还是更新，data:后台传过来的该周期最新一条数据}
 */
function processUpdateData(category, data) {

	switch (category) {
		case "system_info":
			processUpdateSystemData(data);
			break;
		case "controller_info":
			processUpdateControllerData(data);
			break;
		case "interceptor_info":
			processUpdateInterceptorData(data);
			break;
		case "bootedhandler_info":
			processUpdateBootedHandlerData(data);
			break;
		default:
			processUpdateChartData(category, data);
	}

}

/**
 * 处理Controller相关信息
 */
function processUpdateControllerData(data) {
	let tbody = data.map(item => {
		let clazz = item.class;
		let routes = item.routes;

		let content = "";

		routes.forEach((r,i) => {
			let tr = "<tr>";
			if (i == 0) {
				tr += `<td rowspan="${r"${(!routes || routes.length==0)?1:routes.length}"}">${r"${clazz}"}</td>`
			}
			tr += `
				<td>${r"${r.method}"}</td>
				<td class="params">${r"${r.params.join('<br/>')}"}</td>
				<td>${r"${r.url}"}</td>
			`
			content+= tr;
		})

		return content;


	}).join('');
	$("#controller_list").html(tbody);
}
/**
 * 处理ControllerInterceptor相关信息
 */
function processUpdateInterceptorData(data) {
	let tbody = data.map((item,i) => {

		let content = `
			<tr>
				<td>${r"${item.priority}"}</td>
				<td>${r"${item.class}"}</td>
				<td>${r"${item.remark?item.remark:''}"}</td>
			</tr>
		`;


		return content;


	}).join('');
	$("#interceptor_list").html(tbody);
}
/**
 * 处理BootedHandler相关信息
 */
function processUpdateBootedHandlerData(data) {
	let tbody = data.map((item,i) => {

		let content = `
			<tr>
				<td>${r"${i+1}"}</td>
				<td>${r"${item.class}"}</td>
				<td>${r"${item.remark?item.remark:''}"}</td>
			</tr>
		`;


		return content;


	}).join('');
	$("#bootedhandler_list").html(tbody);
}

/**
 * 系统信息
 */
function processUpdateSystemData(data) {
	$("#system_info").html(`
		<div class="fx fx-c_baseline mb10">
			<span class="label">操作系统：</span><span>${r"${data.os}"}</span>
		</div>
		<div class="fx fx-c_baseline mb10">
			<span class="label">CPU：</span><span>${r"${data.cpu}"}</span>
		</div>
		<div class="fx fx-c_baseline mb10">
			<span class="label">内存：</span><span>${r"${data.memory}"}</span>
		</div>
		<div class="fx fx-c_baseline mb10">
			<span class="label">存储：</span><span>${r"${data.store}"}</span>
		</div>
	`);
	if (items["system_store"].chart == null) {
		items["system_store"].chart = echarts.init(document.getElementById("system_store"));
	}
	let option = items["system_store"].option;
	option.yAxis.data = data.storeList.map(item => item.name);
	option.series[0].data = data.storeList.map(item => item.used);
	option.series[1].data = data.storeList.map(item => item.free);
	items["system_store"].chart.setOption(option);
}

/**
 * 处理后端传过来的图表数据
 */
function processUpdateChartData(category, data) {

	items[category].chart.setOption(items[category].option, true);
	let {second, minite, hour} = data;
	//处理秒级数据
	let allData = items[category].allData;
	if (second.size == allData.secondData.length) {
		allData.secondData.shift();
	}
	allData.secondData.push(second.data);
	//处理分钟数据
	if (minite.size != allData.miniteData.length) {
		allData.miniteData.push(minite.data);
	} else {
		let cycleData = minite.data;
		if (cycleData.time != allData.miniteData[allData.miniteData.length-1].time) {
			allData.miniteData.shift();
			allData.miniteData.push(cycleData);
		} else {
			allData.miniteData[allData.miniteData.length-1] = cycleData;
		}
	}
	//处理小时数据
	if (hour.size != allData.hourData.length) {
		allData.hourData.push(hour.data);
	} else {
		let cycleData = hour.data;
		if (cycleData.time != allData.hourData[allData.hourData.length-1].time) {
			allData.hourData.shift();
			allData.hourData.push(cycleData);
		} else {
			allData.hourData[allData.hourData.length-1] = cycleData;
		}
	}
	processChart(category);
}



/**
 * 创建websocket链接
 */
var ws = null;
if ('WebSocket' in window){
	let url = "";
	if (window.location.protocol == 'http:') {
		url += "ws://";
	} else {
		url += "wss://";
	}
	url += location.host+"${basePath?ensure_ends_with("/")}plateform/monitorSocket?token=${token}";
	ws = new WebSocket(url);
}else {
	alert("浏览器不支持");
}

// 连接安生错误的回调方法
ws.onerror = function () {
	console.error("WEBSOCKET发生链接错误");
}

// 连接成功的回调方法
ws.onopen = function (ev) {
	console.log("WebSocket连接成功！");
	initPanels();
}

// 收到消息的回调方法
ws.onmessage = function (ev) {
	console.debug("接收到消息", ev);
	resolveMsg(ev.data);
}

// 连接关闭的回调方法
ws.onclose = function () {
	console.log("WebSocket连接关闭");
}


// 监听窗口关闭事件，防止连接没断关闭窗口。
window.onbeforeunload = function () {
	closeWebSocket();
}



// 关闭websocket连接
function closeWebsocket(){
	ws.close();
}

// 发送消息
function send(data){
	ws.send(JSON.stringify(data));
}
Date.prototype.format = function(fmt) {
	let ret;
	const opt = {
		"y+": this.getFullYear().toString(),        // 年
		"M+": (this.getMonth() + 1).toString(),     // 月
		"d+": this.getDate().toString(),            // 日
		"H+": this.getHours().toString(),           // 时
		"m+": this.getMinutes().toString(),         // 分
		"s+": this.getSeconds().toString()          // 秒
		// 有其他格式化字符需求可以继续添加，必须转化成字符串
	};
	for (let k in opt) {
		ret = new RegExp("(" + k + ")").exec(fmt);
		if (ret) {
			fmt = fmt.replace(ret[1], (ret[1].length == 1) ? (opt[k]) : (opt[k].padStart(ret[1].length, "0")))
		};
	};
	return fmt;
}
</script>
</html>
